package com.atstudent.gmall.cart.service.impl;/*
 * @author: XueYouPeng
 * @time: 23.9.15 下午 3:42
 */

import com.alibaba.fastjson.JSON;
import com.atstudent.gmall.cart.entity.CartItem;
import com.atstudent.gmall.cart.service.CartService;
import com.atstudent.gmall.common.constant.GmallConstant;
import com.atstudent.gmall.common.execption.GmallException;
import com.atstudent.gmall.common.feign.interceptor.AuthUserInfo;
import com.atstudent.gmall.common.feign.product.SkuFeignClient;
import com.atstudent.gmall.common.feign.util.AuthUserInfoUtils;
import com.atstudent.gmall.common.result.Result;
import com.atstudent.gmall.common.result.ResultCodeEnum;
import com.atstudent.gmall.product.entity.SkuInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate<String ,String> redisTemplate;

    @Autowired
    private SkuFeignClient skuFeignClient;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {

        //构建Redis的key
        String redisKey = buildRedisKey();
        //得到JSON字符串数据
        String cartItemJSON = redisTemplate.opsForHash().get(redisKey, String.valueOf(skuId)).toString();
        CartItem cartItem = JSON.parseObject(cartItemJSON, CartItem.class);
        //拿到skuNum数据
        Integer cartItemSkuNum = cartItem.getSkuNum();
        cartItem.setSkuNum(cartItemSkuNum + skuNum);

        //对商品数量进行控制
        if (cartItemSkuNum > 10){
            cartItem.setSkuNum(10);
        }

        //再把数据重新添加到Redis中
        redisTemplate.opsForHash().put(redisKey , String.valueOf(skuId) , JSON.toJSONString(cartItem));
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        String redisKey = buildRedisKey();
        String cartItemJSON = redisTemplate.opsForHash().get(redisKey, String.valueOf(skuId)).toString();
        CartItem cartItem = JSON.parseObject(cartItemJSON, CartItem.class);
        //把前端传过来的isChecked设置进去
        cartItem.setIsChecked(isChecked);
        redisTemplate.opsForHash().put(redisKey , String.valueOf(skuId) , JSON.toJSONString(cartItem));
    }

    @Override
    public void deleteCart(Long skuId) {
        String redisKey = buildRedisKey();
        redisTemplate.opsForHash().delete(redisKey , String.valueOf(skuId));
    }

    @Override
    public List<CartItem> findAllCartItem() {

        //判断用户是否登录
        String userId = AuthUserInfoUtils.getAuthUserInfo().getUserId();
        String userTempId = AuthUserInfoUtils.getAuthUserInfo().getUserTempId();
        if (!StringUtils.isEmpty(userId)){//已登录

            //分别构建用户购物车和临时用户购物车
            String userCartRediskey = GmallConstant.REDIS_CART_PRE + userId;
            String userTempCartRediskey = GmallConstant.REDIS_CART_PRE + userTempId;

            //获取临时购物车数据
            List<CartItem> userTempCartItemList = redisTemplate.opsForHash().values(userTempCartRediskey).stream().map(obj -> {
                //转成json字符串
                String cartItemJSON = obj.toString();
                CartItem cartItem = JSON.parseObject(cartItemJSON, CartItem.class);
                return cartItem;
            }).collect(Collectors.toList());

            //获取用户购物车数据
            List<CartItem> userCartItemList = redisTemplate.opsForHash().values(userCartRediskey).stream().map(obj -> {
                //转成json字符串
                String cartItemJSON = obj.toString();
                CartItem cartItem = JSON.parseObject(cartItemJSON, CartItem.class);
                return cartItem;
            }).collect(Collectors.toList());

            //拿到临时购物车的全部id
            List<Long> userTempCartSkuIds = userTempCartItemList.stream().map(tempCartItem -> tempCartItem.getSkuId()).collect(Collectors.toList());

            //拿到购物车的全部id
            List<Long> userCartSkuIds = userCartItemList.stream().map(cartItem -> cartItem.getSkuId()).collect(Collectors.toList());

            // 合并集合并进行去重
            List<Long> collect = Stream.concat(userCartSkuIds.stream(), userTempCartSkuIds.stream()).distinct().collect(Collectors.toList());
            if (collect.size() > 3){
                throw new GmallException(ResultCodeEnum.CART_ITEM_NUMBER_ERROR) ;
            }

            // 对临时购物车列表进行遍历，获取每一个购物项数据，然后将其添加到用户购物车中
            for (CartItem cartItem : userTempCartItemList){
                //拿到每个数据项的id 看用户购物车中是否存在
                Long skuId = cartItem.getSkuId();
                Boolean hasKey = redisTemplate.opsForHash().hasKey(userCartRediskey, String.valueOf(skuId));
                if (hasKey){//如果有 只对数量进行加操作

                    String userCartItemJSON = redisTemplate.opsForHash().get(userCartRediskey, String.valueOf(skuId)).toString();
                    CartItem userCartItem = JSON.parseObject(userCartItemJSON, CartItem.class);
                    userCartItem.setSkuNum(userCartItem.getSkuNum() + cartItem.getSkuNum());
                    //拿到skuNum 对他的数量进行限制处理
                    Integer skuNum = userCartItem.getSkuNum();
                    if (skuNum > 10){
                        userCartItem.setSkuNum(10);
                    }
                    //在存到Redis中
                    redisTemplate.opsForHash().put(userCartRediskey , String.valueOf(skuId) , JSON.toJSONString(userCartItem));
                }else {//如果没有这个商品 直接把临时购物车的数据存到真实购物车中
                    redisTemplate.opsForHash().put(userCartRediskey , String.valueOf(skuId) , JSON.toJSONString(cartItem));
                }
            }

            //一切操作完后删掉临时购物车
            redisTemplate.delete(userTempCartRediskey);

            // 获取用户购物车数据进行返回
            List<CartItem> cartItemList = redisTemplate.opsForHash().values(userCartRediskey).stream().map(obj -> {
                String cartItemJSON = obj.toString();
                CartItem cartItem = JSON.parseObject(cartItemJSON, CartItem.class);

                //更新下价格
                updateSkuPrice(cartItem , userCartRediskey);

                return cartItem;
            }).collect(Collectors.toList());

            return cartItemList;

        }else {//未登录

            //查的就是临时购物车的数据
            String redisKey = buildRedisKey();
            //根据大key查询所有数据
            List<Object> objectList = redisTemplate.opsForHash().values(redisKey);
            List<CartItem> cartItemList = objectList.stream().map(obj -> {
                String cartItemJSON = obj.toString();
                CartItem cartItem = JSON.parseObject(cartItemJSON, CartItem.class);

                //查看购物车时 更新下价格
                updateSkuPrice(cartItem , redisKey);
                return cartItem;
            }).collect(Collectors.toList());

            return cartItemList;
        }

    }

    private void updateSkuPrice(CartItem cartItem, String redisKey) {

        Result<SkuInfo> skuInfoBySkuId = skuFeignClient.findSkuInfoBySkuId(cartItem.getSkuId());
        SkuInfo skuInfo = skuInfoBySkuId.getData();
        cartItem.setCartPrice(skuInfo.getPrice());

        //更新后的数据 写入到Redis中
        redisTemplate.opsForHash().put(redisKey , String.valueOf(cartItem.getSkuId()) , JSON.toJSONString(cartItem));
    }

    //构建Redis的数据key
    private String buildRedisKey() {

        AuthUserInfo authUserInfo = AuthUserInfoUtils.getAuthUserInfo();
        if (authUserInfo != null){
            String userId = authUserInfo.getUserId();
            String userTempId = authUserInfo.getUserTempId();
            if (!StringUtils.isEmpty(userId)){
                return GmallConstant.REDIS_CART_PRE + userId ;
            }else {
                return GmallConstant.REDIS_CART_PRE + userTempId ;
            }
        }else {
            return null;
        }
    }
}
